namespace Microsoft.ServiceModel.Samples.Discovery.Protocol
{
    using System;
    using System.Xml;
    using System.Diagnostics;
    using System.Collections.Generic;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    
    public class ProbeRequest : FindRequest
    {
        Probe probe;
        const int MaxProbeMatchesPerMessage = 100;

        internal ProbeRequest(Probe probe, OperationContext opContext)
            : base(opContext)
        {
            this.probe = probe;
        }

        public Probe Probe
        {
            get
            {
                return this.probe;
            }
        }

        public void Reply(ProbeMatch probeMatch)
        {
            EnsureResponseChannel();

            ProbeMatches matches = new ProbeMatches();
            matches.Items = new ProbeMatch[1];
            matches.Items[0] = probeMatch;

            Reply(matches);
        }

        public void Reply(ServiceProperties properties)
        {
            EnsureResponseChannel();

            ProbeMatches matches = new ProbeMatches();
            matches.Items = new ProbeMatch[1];
            matches.Items[0] = ProbeMatch.FromServiceProperties(properties);

            Reply(matches);
        }

        public void Reply(IEnumerable<ServiceProperties> propertiesCollection)
        {
            EnsureResponseChannel();

            if (string.Compare(ReplyTo.Uri.Scheme, ProtocolStrings.UdpScheme, 
                StringComparison.OrdinalIgnoreCase) == 0)
            {
                // send one response at a time
                foreach (ServiceProperties properties in propertiesCollection)
                    Reply(ProbeMatch.FromServiceProperties(properties));
            }
            else
            {
                // send multiple responses at a time.
            
                List<ProbeMatch> matches = new List<ProbeMatch>();
                foreach (ServiceProperties properties in propertiesCollection)
                {
                    matches.Add(ProbeMatch.FromServiceProperties(properties));
                    if (matches.Count == MaxProbeMatchesPerMessage)
                    {
                        ProbeMatches probeMatches = new ProbeMatches();
                        probeMatches.Items = matches.ToArray();
                        Reply(probeMatches);
                        matches.Clear();
                    }
                }

                if (matches.Count != 0)
                {
                    ProbeMatches probeMatches = new ProbeMatches();
                    probeMatches.Items = matches.ToArray();
                    Reply(probeMatches);
                    matches.Clear();
                }
            }
        }

        
        public void Reply(ProbeMatches probeMatches)
        {
            EnsureResponseChannel();

            using (new OperationContextScope((IContextChannel)ResponseChannel))
            {
                AddOutgoingMessageHeaders();

                ProbeMatchesMessage message = new ProbeMatchesMessage();
                message.ProbeMatches = probeMatches;
                ResponseChannel.ProbeMatchOperation(message);
            }
        }
    }
}
